home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / Amiga_Mail_Vol2 / Archives / Plain / mj90.lha / ProPage / CollisionDetectV-25.ppd (.txt) < prev    next >
Encoding:
Professional Page Document  |  1991-06-12  |  122.5 KB  |  1,452 lines

  1. Professional Page V1.2
  2. dPENV
  3. Helvetica
  4. Bookman
  5. Courier
  6. zapfdingbats
  7. 6Green
  8. Yellow
  9. &Magenta
  10. vCyan
  11. CollDet.ppg
  12. DNo Author
  13. ,wPPAG
  14. .LPSGR
  15. Black
  16. Black
  17. 2FPBOX
  18. O\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  19. N9PBOX
  20. O[PTXT
  21. U\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 30\.
  22. w\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  23. EPBOX
  24. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  25. @PSGR
  26. Black
  27. Black
  28.     PPAG
  29. lPBOX
  30. cPSGR
  31. Black
  32. Black
  33. hPBOX
  34. zPTXT
  35. t\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  36. {PBOX
  37. p\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 31\I\O\ff<Bookman>\fs<14>\jl
  38. R\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  39. 5?PBOX
  40. 9dPTXT
  41. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  42. Y1PBOX
  43. Black
  44. Black
  45. `SPBOX
  46. Black
  47. Black
  48. fwPBOX
  49. jDPBOX
  50. lEPTXT
  51. \n\B\ff<Times>\fs<30>\lr<155>\ls<0.000>\ps<100>\t<0>\c<Black>
  52. \lr<115>Collision Detection Between Animation Objects\fs<12>
  53. \fs<14>by Ken Farinsky\fs<12>
  54. \bCollision detection allows the system to manage Gel-to-Border and Gel-to-Gel collision handling for an application.  "Gels" are VSprite-based objects that may be displayed and moved about the Amiga display.  These objects include VSprites (Virtual Sprites), Bobs (Blitter Objects), and AnimObs (Animation Objects).  For a detailed discussion of collision detection between simple Gels (such as VSprites and Bobs), see the "Graphics: Sprites, Bobs and Animation" chapter in the \IROM Kernel Manual: Libraries and Devices\i.
  55. The basic premise of Amiga collision detection is to call a user supplied collision routine when two objects overlap.  This is complicated by two further enhancements.  First, borders are counted as objects and special-case processing of collisions is provided between Gels and the border.  Second, each Gel has two masks that indicate how pairs of objects will react when they collide.
  56. Collision detection between objects such as VSprites and Bobs is conceptually very simple.  Each object is built upon a single underlying structure, the VSprite structure.  After the Gel has been added to the system, the DoCollision() routine scans the list of VSprites for overlapping objects and calls the appropriate user-supplied collision routine in the event of a collision.  Since there is a one-to-one correspondence between VSprites and objects, it is obvious which VSprite structure belongs to which object on the screen.
  57. \BAnimation Objects Are Not Simple Gels\b
  58. Animation Objects contain multiple VSprite structures which are linked to form a larger object.  When the object is being animated, the system cycles through these underlying components, displaying each at the appropriate moment.  At any given point in time the system may be in the process of removing the last displayed component and adding in the next one.  During such a component switch, the system will have two VSprites added for a single object: one is in the process of being removed and one is in the process of being displayed.
  59. \BSpecial Initialization Steps for Complex Gel Collision Detection
  60. When setting-up a multi-component Gel, each underlying VSprite structure must be initialized for collision, as the system will not look to the others for more information.  An AnimOb's collision detection information need not be static.  The collision information can change from frame to frame in the same manner image data can change.  The example shows a special case, where all frames are similar enough that they have identical collision information.
  61. The following fields in the VSprite structure must be properly initialized for system collision detection: HitMask, MeMask, BorderLine and CollMask.  HitMask and MeMask tell the system which collision routine to call when a collision is detected.  BorderLine and CollMask are "shadow masks" that are used to determine if this component overlaps any other object.  These values are set just as they would be for a single VSprite or a Bob.
  62. Note that it is impossible for components of a single AnimOb's sequence to collide with one another.  However, in an AnimOb that contains multiple sequences, it is possible for a component in one sequence to collide with a component from a different sequence.  This can be prevented through careful selection of HitMask and MeMask values, or can be detected in the individual collision routines.
  63. \BWhat Happens When Complex Gels Collide
  64. Collisions between Animation Objects \Ishould\i be fairly simple to process.  The DoCollision() routine \Ishould\i examine all displayed objects for both overlap of objects and for correct interaction between the HitMask and MeMask, then call the appropriate collision routine.\lr<120>
  65. Unfortunately, the DoCollision() routine does not ignore the previous AnimOb component, which is in the process of being removed from the display.  These components are moved by the system to a position well above and to the left of the visible display.  When the Gels are next drawn, the removed component will be moved off-screen, causing it to disappear from the display.  At the same time, the new component will be drawn on-screen.  This would not be a problem if the removed components did not overlap, however, all components that are being removed are positioned at the same off-screen location.  This means that they all overlap and collisions will occur between all pairs of components that are in the process of being removed.
  66. \BThe \ff<Courier>BOBSAWAY\ff<Times> Flag Comes to the Rescue\b
  67. To handle collisions between pairs of AnimObs, the Gel-to-Gel collision routines must ignore the objects that are being removed.  There are two ways to handle this.  The first is to check for large negative position values in the X and Y variables of the VSprite structure.  This works, but is not the best way to check for removal.  The second, and preferred method, is to look at the flags of the associated Bob.  If the \ff<Courier>BOBSAWAY\ff<Times> flag is set, then the bob is being removed and should not be used in the collision routines.  Note that this has been changed for 2.0, which will only look at active VSprites for collision detection.
  68. The example code is made up of four files:
  69. 1)\sanimtools.h       \s\s- include file necessary to use animtools.
  70. 2)\sanimtools_proto.h\s\s- prototypes for animtools functions.
  71. 3)\sanimtools.c      \s\s- animtools functions.  These simplify the use of the animation 
  72. \s\s\s\s\s\s\s\ssub-system.
  73. 4)\scollide.c         \s\s\s- example code.
  74. The example code was published in the latest release of the \IROM Kernel Manual: Libraries & Devices\i.  It has been updated and reprinted here.  The example can be compiled and linked using Lattice C with these commands:
  75. \ff<Courier>\fs<9>lc -b1 -cfist -v -y -ocollide.o collide.c
  76. lc -b1 -cfist -v -y -oanimtools.o animtools.c
  77. blink from lib:c.o collide.o animtools.o library 
  78. \s                        lib:lc.lib lib:amiga.lib to collide\.
  79. t\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  80. U\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 25\.
  81. R\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  82. [7PTXT
  83. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  84. ~ZPSGR
  85. Black
  86. Black
  87. T\n\I\ff<Times>\fs<12>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>May/June 1990 \.
  88. ePPAG
  89. ,PBOX
  90. Black
  91. Black
  92. aPBOX
  93. O\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  94. pPTXT
  95. U\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 26\.
  96. EPBOX
  97. w\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  98. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  99. Black
  100. Black
  101. >:PBOX
  102. Black
  103. Black
  104. HAPBOX
  105. t\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  106. t[PBOX
  107. xmPTXT
  108. p\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 27\I\O\ff<Bookman>\fs<14>\jl
  109. R\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  110. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  111. ,PBOX
  112. TPSGR
  113. Black
  114. Black
  115. aPPAG
  116. iPBOX
  117. Black
  118. Black
  119. \n\B\ff<Courier>\fs<7>\lr<124>\ls<0.000>\ps<100>\t<0>\c<Black>1) /* File: animtools.h */\b
  120. #ifndef GELTOOLS_H
  121. #define GELTOOLS_H
  122. /* these data structures are used by the functions in animtools.c to
  123. ** allow for an easier interface to the animation system.
  124. /* data structure to hold information for a new vsprite.
  125. ** note that:
  126. **     NEWVSPRITE myNVS;
  127. ** is equivalent to:
  128. **     struct newVSprite myNVS;
  129. typedef struct newVSprite
  130. \sWORD           *nvs_Image;      /* image data for the vsprite   */
  131. \sWORD           *nvs_ColorSet;   /* color array for the vsprite  */
  132. \sSHORT           nvs_WordWidth;  /* width in words               */
  133. \sSHORT           nvs_LineHeight; /* height in lines              */
  134. \sSHORT           nvs_ImageDepth; /* depth of the image           */
  135. \sSHORT           nvs_X;          /* initial x position           */
  136. \sSHORT           nvs_Y;          /* initial y position           */
  137. \sSHORT           nvs_Flags;      /* vsprite flags                */
  138. /* THIS HAS CHANGED for amiga mail. **********************************
  139. ** Add two lines to the NEWVSPRITE structure.
  140. ** This allows the created VSprite structures to be initialized with
  141. ** HitMask and MeMask information.
  142. \sUSHORT          nvs_HitMask;    /* Hit mask.                    */
  143. \sUSHORT          nvs_MeMask;     /* Me mask.                     */
  144. ** END OF CHANGE for amiga mail.    **********************************
  145. \s} NEWVSPRITE;
  146. /* data structure to hold information for a new bob.
  147. ** note that:
  148. **     NEWBOB myNBob;
  149. ** is equivalent to:
  150. **     struct newBob myNBob;
  151. typedef struct newBob
  152. \sWORD       *nb_Image;       /* image data for the bob       */
  153. \sSHORT       nb_WordWidth;   /* width in words               */
  154. \sSHORT       nb_LineHeight;  /* height in lines              */
  155. \sSHORT       nb_ImageDepth;  /* depth of the image           */
  156. \sSHORT       nb_PlanePick;   /* planes that get image data   */
  157. \sSHORT       nb_PlaneOnOff;  /* unused planes to turn on     */
  158. \sSHORT       nb_BFlags;      /* bob flags                    */
  159. \sSHORT       nb_DBuf;        /* 1=double buf, 0=not          */
  160. \sSHORT       nb_RasDepth;    /* depth of the raster          */
  161. \sSHORT       nb_X;           /* initial x position           */
  162. \sSHORT       nb_Y;           /* initial y position           */
  163. /* THIS HAS CHANGED for amiga mail. **********************************
  164. ** Add two lines to the NEWBOB structure.
  165. ** This is only used to pass the information to the VSprite structure
  166. ** in the makeBob() routine.
  167. \sUSHORT      nb_HitMask;     /* Hit mask.                    */
  168. \sUSHORT      nb_MeMask;      /* Me mask.                     */
  169. ** END OF CHANGE for amiga mail.    **********************************
  170. \s} NEWBOB ;
  171. /* data structure to hold information for a new animation component.
  172. ** note that:
  173. **     NEWANIMCOMP myNAC;
  174. ** is equivalent to:
  175. **     struct newAnimComp myNAC;
  176. typedef struct newAnimComp
  177. \sWORD  (*nac_Routine)(); /* routine called when Comp is displayed.   */
  178. \sSHORT   nac_Xt;         /* initial delta offset position.           */
  179. \sSHORT   nac_Yt;         /* initial delta offset position.           */
  180. \sSHORT   nac_Time;       /* Initial Timer value.                     */
  181. \sSHORT   nac_CFlags;     /* Flags for the Component.                 */
  182. \s} NEWANIMCOMP;
  183. /* data structure to hold information for a new animation sequence.
  184. ** note that:
  185. **     NEWANIMSEQ myNAS;
  186. ** is equivalent to:
  187. **     struct newAnimSeq myNAS;
  188. typedef struct newAnimSeq
  189. \sstruct AnimOb  *nas_HeadOb; /* common Head of Object.               */
  190. \sWORD   *nas_Images;         /* array of Comp image data             */
  191. \sSHORT  *nas_Xt;             /* arrays of initial offsets.           */
  192. \sSHORT  *nas_Yt;             /* arrays of initial offsets.           */
  193. \sSHORT  *nas_Times;          /* array of Initial Timer value.        */
  194. \sWORD (**nas_Routines)();    /* Array of fns called when comp drawn  */
  195. \sSHORT   nas_CFlags;         /* Flags for the Component.             */
  196. \sSHORT   nas_Count;          /* Num Comps in seq (= arrays size)     */
  197. /* THIS HAS CHANGED for amiga mail. **********************************
  198. ** Delete two lines from the NEWANIMSEQ structure.
  199. ** These are removed becaues the information is now contained in the
  200. ** NEWBOB and NEWVSPRITE structures.
  201. **  SHORT   nas_HitMask;
  202. **  SHORT   nas_MeMask;
  203. ** END OF CHANGE for amiga mail.    **********************************
  204. \sSHORT   nas_SingleImage;    /* one (or count) images.               */
  205. \s} NEWANIMSEQ;
  206. #endif
  207. \B2) /* File: animtools_proto.h */\b
  208. struct GelsInfo *setupGelSys(struct RastPort *rPort, BYTE reserved);
  209. VOID cleanupGelSys(struct GelsInfo *gInfo, struct RastPort *rPort);
  210. struct VSprite *makeVSprite(NEWVSPRITE *nVSprite);
  211. struct Bob *makeBob(NEWBOB *nBob);
  212. struct AnimComp *makeComp(NEWBOB *nBob, NEWANIMCOMP *nAnimComp);
  213. struct AnimComp *makeSeq(NEWBOB *nBob, NEWANIMSEQ *nAnimSeq);
  214. VOID freeVSprite(struct VSprite *vsprite);
  215. VOID freeBob(struct Bob *bob, LONG rasdepth);
  216. VOID freeComp(struct AnimComp *myComp, LONG rasdepth);
  217. VOID freeSeq(struct AnimComp *headComp, LONG rasdepth);
  218. VOID freeOb(struct AnimOb *headOb, LONG rasdepth);
  219. \B3) /* animtools.c 19oct89 \boriginal code by Dave Lucas.
  220. ** rework by (CATS)
  221. ** \KThis file is a collection of tools which are used with the VSprite, Bob\k
  222. ** and Animation system software. It is intended as a useful EXAMPLE, and
  223. ** while it shows what must be done, it is not the only way to do it.
  224. ** If Not Enough Memory, or error return, each cleans up after itself
  225. ** before returning.
  226. ** NOTE:  these routines assume a very specific structure to the
  227. ** gel lists.  make sure that you use the correct pairs together
  228. ** (i.e. makeOb()/freeOb(), etc.)
  229. ** lattice c 5.04
  230. ** lc -b1 -cfist -v -y -oanimtools.o animtools.c
  231. #include <exec/types.h>
  232. #include <exec/memory.h>
  233. #include <graphics/gfx.h>
  234. #include <graphics/gels.h>
  235. #include <graphics/clip.h>
  236. #include <graphics/rastport.h>
  237. #include <graphics/view.h>
  238. #include <graphics/gfxbase.h>
  239. /* THIS HAS CHANGED for amiga mail. **********************************
  240. ** In the RKM it was assumed that animtools stuff was in a different
  241. ** directory from the example program.
  242. **      #include "/animtools/animtools.h"
  243. **      #include "/animtools/animtools_proto.h"
  244. ** Now they are in the same directory as the example:
  245. ** END OF CHANGE for amiga mail.    **********************************
  246. #include "animtools.h"
  247. #include "animtools_proto.h"
  248. #include <proto/all.h>
  249. /*-------------------------------------------------------------
  250. ** setup the gels system.  After this call is made you can use
  251. ** vsprites, bobs, anim comps, and anim obs.
  252. ** note that this links the GelsInfo structure into the rast port,
  253. ** and calls InitGels().
  254. ** all resources are properly freed on failure.
  255. ** It uses information in your RastPort structure to establish
  256. ** boundary collision defaults at the outer edges of the raster.
  257. ** This routine sets up for everything - collision detection and all.
  258. ** You must already have run LoadView before ReadyGelSys is called.
  259. struct GelsInfo *setupGelSys(struct RastPort *rPort, BYTE reserved)
  260. struct GelsInfo *gInfo;
  261. struct VSprite  *vsHead;
  262. struct VSprite  *vsTail;
  263. if (NULL != (gInfo =
  264. \s(struct GelsInfo *)AllocMem((LONG)sizeof(struct GelsInfo), MEMF_CLEAR)))
  265. \sif (NULL != (gInfo->nextLine =
  266. \s    (WORD *)AllocMem((LONG)sizeof(WORD) * 8, MEMF_CLEAR)))
  267. \s    {
  268. \s    if (NULL != (gInfo->lastColor =
  269. \s        (WORD **)AllocMem((LONG)sizeof(LONG) * 8, MEMF_CLEAR)))
  270. \s        {
  271. \s        if (NULL != (gInfo->collHandler =
  272. \s            (struct collTable *)AllocMem((LONG)sizeof(struct 
  273. \s\s\s\s\s\s\s\s\s\s\s\scollTable), MEMF_CLEAR)))
  274. \s            {
  275. \s            if (NULL != (vsHead = (struct VSprite *)AllocMem(
  276. \s                (LONG)sizeof(struct VSprite), MEMF_CLEAR)))
  277. \s                {
  278. \s                if (NULL != (vsTail = (struct VSprite *)AllocMem(
  279. \s                    (LONG)sizeof(struct VSprite), MEMF_CLEAR)))
  280. \s                    {
  281. \s                    gInfo->sprRsrvd   = reserved;
  282. /* THIS HAS CHANGED for amiga mail. **********************************
  283. ** In the RKM leftmost and topmost were set to zero.
  284. **                      gInfo->leftmost   = 0;
  285. **                      gInfo->topmost    = 0;
  286. ** This has been changed to one to better keep items inside the
  287. ** boundaries of the display.
  288. \s                    gInfo->leftmost   = 1;
  289. \s                    gInfo->topmost    = 1;
  290. ** END OF CHANGE for amiga mail.    **********************************
  291. \s                    gInfo->rightmost  =
  292. \s                        (rPort->BitMap->BytesPerRow << 3) - 1;
  293. \s                    gInfo->bottommost = rPort->BitMap->Rows - 1;
  294. \s                    rPort->GelsInfo = gInfo;
  295. \s                    InitGels(vsHead, vsTail, gInfo);
  296. \s                    return(gInfo);
  297. \s                    }
  298. \s                FreeMem(vsHead, (LONG)sizeof(*vsHead));
  299. \s                }
  300. \s            FreeMem(gInfo->collHandler, 
  301. \s\s\s\s\s\s\s\s\s(LONG)sizeof(struct collTable));
  302. \s            }
  303. \s        FreeMem(gInfo->lastColor, (LONG)sizeof(LONG) * 8);
  304. \s        }
  305. \s    FreeMem(gInfo->nextLine, (LONG)sizeof(WORD) * 8);
  306. \s    }
  307. \sFreeMem(gInfo, (LONG)sizeof(*gInfo));
  308. return(NULL);
  309. /*-------------------------------------------------------------
  310. ** free all of the stuff allocated by setupGelSys().
  311. ** only call this routine if setupGelSys() returned successfully.
  312. ** the GelsInfo structure is the one returned by setupGelSys().
  313. ** It also unlinks the GelsInfo from the RastPort.
  314. VOID cleanupGelSys(struct GelsInfo *gInfo, struct RastPort *rPort)
  315. rPort->GelsInfo = NULL;
  316. FreeMem(gInfo->collHandler, (LONG)sizeof(struct collTable));
  317. FreeMem(gInfo->lastColor, (LONG)sizeof(LONG) * 8);
  318. FreeMem(gInfo->nextLine, (LONG)sizeof(WORD) * 8);
  319. FreeMem(gInfo->gelHead, (LONG)sizeof(struct VSprite));
  320. FreeMem(gInfo->gelTail, (LONG)sizeof(struct VSprite));
  321. FreeMem(gInfo, (LONG)sizeof(*gInfo));
  322. /*-------------------------------------------------------------
  323. ** create a VSprite from the information given in nVSprite.
  324. ** use freeVSprite() to free this gel.
  325. struct VSprite *makeVSprite(NEWVSPRITE *nVSprite)
  326. struct VSprite *vsprite;
  327. LONG            line_size;
  328. LONG            plane_size;
  329. line_size = (LONG)sizeof(WORD) * nVSprite->nvs_WordWidth;
  330. plane_size = line_size * nVSprite->nvs_LineHeight;
  331. if (NULL != (vsprite =
  332. \s(struct VSprite *)AllocMem((LONG)sizeof(struct VSprite), MEMF_CLEAR)))
  333. \sif (NULL != (vsprite->BorderLine =
  334. \s    (WORD *)AllocMem(line_size, MEMF_CHIP)))
  335. \s    {
  336. \s    if (NULL != (vsprite->CollMask =
  337. \s        (WORD *)AllocMem(plane_size, MEMF_CHIP)))
  338. \s        {
  339. \s        vsprite->Y          = nVSprite->nvs_Y;
  340. \s        vsprite->X          = nVSprite->nvs_X;
  341. \s        vsprite->Flags      = nVSprite->nvs_Flags;
  342. \s        vsprite->Width      = nVSprite->nvs_WordWidth;
  343. \s        vsprite->Depth      = nVSprite->nvs_ImageDepth;
  344. \s        vsprite->Height     = nVSprite->nvs_LineHeight;
  345. /* THIS HAS CHANGED for amiga mail. **********************************
  346. ** In the RKM, the vsprite HitMask and MeMask were set to an arbitrary
  347. ** value (it was assumed that the programmer would later patch these
  348. ** values if collision detection was required!)
  349. **          vsprite->MeMask     = 1;
  350. **          vsprite->HitMask    = 1;
  351. ** Here, we have changed the NEWVSPRITE structure to contain these
  352. ** values, so this routine can set-up both of them.
  353. \s        vsprite->MeMask     = nVSprite->nvs_MeMask;
  354. \s        vsprite->HitMask    = nVSprite->nvs_HitMask;
  355. ** END OF CHANGE for amiga mail.    **********************************
  356. \s        vsprite->ImageData  = nVSprite->nvs_Image;
  357. \s        vsprite->SprColors  = nVSprite->nvs_ColorSet;
  358. \s        vsprite->PlanePick  = 0x00;
  359. \s        vsprite->PlaneOnOff = 0x00;
  360. \s        InitMasks(vsprite);
  361. \s        return(vsprite);
  362. \s        }
  363. \s    FreeMem(vsprite->BorderLine, line_size);
  364. \s    }
  365. \sFreeMem(vsprite, (LONG)sizeof(*vsprite));
  366. return(NULL);
  367. /*-------------------------------------------------------------
  368. ** create a Bob from the information given in nBob.
  369. ** use freeBob() to free this gel.
  370. ** A VSprite is created for this bob.
  371. ** This routine properly allocates all double buffered information
  372. ** if it is required.
  373. struct Bob *makeBob(NEWBOB *nBob)
  374. struct Bob         *bob;
  375. struct VSprite     *vsprite;
  376. NEWVSPRITE          nVSprite ;
  377. LONG                rassize;
  378. rassize = (LONG)sizeof(UWORD) *
  379. \s        nBob->nb_WordWidth * nBob->nb_LineHeight * nBob->nb_RasDepth;
  380. if (NULL != (bob =
  381. \s(struct Bob *)AllocMem((LONG)sizeof(struct Bob), MEMF_CLEAR)))
  382. \sif (NULL != (bob->SaveBuffer = (WORD *)AllocMem(rassize, MEMF_CHIP)))
  383. \s    {
  384. \s    nVSprite.nvs_WordWidth  = nBob->nb_WordWidth;
  385. \s    nVSprite.nvs_LineHeight = nBob->nb_LineHeight;
  386. \s    nVSprite.nvs_ImageDepth = nBob->nb_ImageDepth;
  387. \s    nVSprite.nvs_Image      = nBob->nb_Image;
  388. \s    nVSprite.nvs_X          = nBob->nb_X;
  389. \s    nVSprite.nvs_Y          = nBob->nb_Y;
  390. \s    nVSprite.nvs_ColorSet   = NULL;
  391. \s    nVSprite.nvs_Flags      = nBob->nb_BFlags;
  392. /* THIS HAS CHANGED for amiga mail. **********************************
  393. ** The structure of the program has been changed to pass the values
  394. ** of the HitMask and the MeMask down to the VSprite structure.
  395. ** Push the values into the NEWVSPRITE structure for use in
  396. ** makeVSprite().
  397. \s    nVSprite.nvs_MeMask     = nBob->nb_MeMask;
  398. \s    nVSprite.nvs_HitMask    = nBob->nb_HitMask;
  399. ** END OF CHANGE for amiga mail.    **********************************
  400. \s    if ((vsprite = makeVSprite(&nVSprite)) != NULL)
  401. \s        {
  402. \s        vsprite->PlanePick = nBob->nb_PlanePick;
  403. \s        vsprite->PlaneOnOff = nBob->nb_PlaneOnOff;
  404. \s        vsprite->VSBob   = bob;
  405. \s        bob->BobVSprite  = vsprite;
  406. \s        bob->ImageShadow = vsprite->CollMask;
  407. \s        bob->Flags       = 0;
  408. \s        bob->Before      = NULL;
  409. \s        bob->After       = NULL;
  410. \s        bob->BobComp     = NULL;
  411. \s        if (nBob->nb_DBuf)
  412. \s            {
  413. \s            if (NULL != (bob->DBuffer = (struct DBufPacket *)AllocMem(
  414. \s                (LONG)sizeof(struct DBufPacket), MEMF_CLEAR)))
  415. \s                {
  416. \s                if (NULL != (bob->DBuffer->BufBuffer =
  417. \s                    (WORD *)AllocMem(rassize, MEMF_CHIP)))
  418. \s                    {
  419. \s                    return(bob);
  420. \s                    }
  421. \s                FreeMem(bob->DBuffer,
  422. \s\s\s\s\s\s\s\s(LONG)sizeof(struct DBufPacket));
  423. \s                }
  424. \s            }
  425. \s        else
  426. \s            {
  427. \s            bob->DBuffer = NULL;
  428. \s            return(bob);
  429. \s            }
  430. \s        freeVSprite(vsprite);
  431. \s        }
  432. \s    FreeMem(bob->SaveBuffer, rassize);
  433. \s    }
  434. \sFreeMem(bob, (LONG)sizeof(*bob));
  435. return(NULL);
  436. /*-------------------------------------------------------------
  437. ** create a Animation Component from the information given in nAnimComp
  438. ** and nBob.
  439. ** use freeComp() to free this gel.
  440. ** makeComp calls makeBob(), and links the bob into a AnimComp.
  441. struct AnimComp *makeComp(NEWBOB *nBob, NEWANIMCOMP *nAnimComp)
  442. struct Bob      *compBob;
  443. struct AnimComp *aComp;
  444. if ((aComp = AllocMem((LONG)sizeof(struct AnimComp),MEMF_CLEAR)) != NULL)
  445. \sif ((compBob = makeBob(nBob)) != NULL)
  446. \s    {
  447. \s    compBob->After   = NULL;  /* Caller can deal with these later. */
  448. \s    compBob->Before  = NULL;
  449. \s    compBob->BobComp = aComp;   /* Link 'em up. */
  450. \s    aComp->AnimBob      = compBob;
  451. \s    aComp->TimeSet      = nAnimComp->nac_Time; /* Num ticks active. */
  452. \s    aComp->YTrans       = nAnimComp->nac_Yt; /* Offset rel to HeadOb */
  453. \s    aComp->XTrans       = nAnimComp->nac_Xt;
  454. \s    aComp->AnimCRoutine = nAnimComp->nac_Routine;
  455. \s    aComp->Flags        = nAnimComp->nac_CFlags;
  456. \s    aComp->Timer        = 0;
  457. \s    aComp->NextSeq      = NULL;
  458. \s    aComp->PrevSeq      = NULL;
  459. \s    aComp->NextComp     = NULL;
  460. \s    aComp->PrevComp     = NULL;
  461. \s    aComp->HeadOb       = NULL;
  462. \s    return(aComp);
  463. \s    }
  464. \sFreeMem(aComp, (LONG)sizeof(struct AnimComp));
  465. return(NULL);
  466. /*-------------------------------------------------------------
  467. ** create an Animation Sequence from the information given in nAnimSeq
  468. ** and nBob.
  469. ** use freeSeq() to free this gel.
  470. ** this routine creates a linked list of animation components which
  471. ** make up the animation sequence.
  472. ** It links them all up, making a circular list of the PrevSeq
  473. ** and NextSeq pointers. That is to say, the first component of the
  474. ** sequences' PrevSeq points to the last component; the last component of
  475. ** the sequences' NextSeq points back to the first component.
  476. ** If dbuf is on, the underlying Bobs'll be set up for double buffering.
  477. ** If singleImage is non-zero, the pImages pointer is assumed to point to
  478. ** an array of only one image, instead of an array of 'count' images, and
  479. ** all Bobs will use the same image.
  480. struct AnimComp *makeSeq(NEWBOB *nBob, NEWANIMSEQ *nAnimSeq)
  481. int seq;
  482. struct AnimComp *firstCompInSeq = NULL;
  483. struct AnimComp *seqComp = NULL;
  484. struct AnimComp *lastCompMade = NULL;
  485. \lr<120>LONG image_size;
  486. NEWANIMCOMP nAnimComp;
  487. /* get the initial image.  this is the only image that is used
  488. ** if nAnimSeq->nas_SingleImage is non-zero.
  489. nBob->nb_Image = nAnimSeq->nas_Images;
  490. image_size = nBob->nb_LineHeight * nBob->nb_ImageDepth * nBob->nb_WordWidth;
  491. /* for each comp in the sequence */
  492. for (seq = 0; seq < nAnimSeq->nas_Count; seq++)
  493. \snAnimComp.nac_Xt        = *(nAnimSeq->nas_Xt + seq);
  494. \snAnimComp.nac_Yt        = *(nAnimSeq->nas_Yt + seq);
  495. \snAnimComp.nac_Time      = *(nAnimSeq->nas_Times + seq);
  496. \snAnimComp.nac_Routine   = nAnimSeq->nas_Routines[seq];
  497. \snAnimComp.nac_CFlags    = nAnimSeq->nas_CFlags;
  498. \sif ((seqComp = makeComp(nBob, &nAnimComp)) == NULL)
  499. \s    {
  500. \s    if (firstCompInSeq != NULL)
  501. \s        freeSeq(firstCompInSeq, (LONG)nBob->nb_RasDepth);
  502. \s    return(NULL);
  503. \s    }
  504. /* THIS HAS CHANGED for amiga mail. **********************************
  505. ** Remove these two lines from the RKM.  This is because we are now
  506. ** passing the HitMask and MeMask directly down to the VSprite structure.
  507. ** NOTE that the deleted technique only sets up the two values for one
  508. ** VSprite in the AnimComp.  The new technique (used in this example)
  509. ** correctly does the set-up of all the VSprites in the AnimComp.
  510. **  seqComp->AnimBob->BobVSprite->HitMask = nAnimSeq->nas_HitMask;
  511. **  seqComp->AnimBob->BobVSprite->MeMask = nAnimSeq->nas_MeMask;
  512. ** END OF CHANGE for amiga mail.    **********************************
  513. \sseqComp->HeadOb = nAnimSeq->nas_HeadOb;
  514. \s/* Make a note of where the first component is. */
  515. \sif (firstCompInSeq == NULL)
  516. \s    firstCompInSeq = seqComp;
  517. \s/* link the component into the list */
  518. \sif (lastCompMade != NULL)
  519. \s    lastCompMade->NextSeq = seqComp;
  520. \sseqComp->NextSeq = NULL;
  521. \sseqComp->PrevSeq = lastCompMade;
  522. \slastCompMade = seqComp;
  523. \s/* If nAnimSeq->nas_SingleImage is zero,
  524. \s** the image array has nAnimSeq->nas_Count images.
  525. \sif (!nAnimSeq->nas_SingleImage)
  526. \s    nBob->nb_Image += image_size;
  527. /* On The last component in the sequence, set Next/Prev to make
  528. ** the linked list a loop of components.
  529. lastCompMade->NextSeq = firstCompInSeq;
  530. firstCompInSeq->PrevSeq = lastCompMade;
  531. return(firstCompInSeq);
  532. }\lr<124>
  533. /*-------------------------------------------------------------
  534. ** free the data created by makeVSprite()
  535. ** assumes images deallocated elsewhere.
  536. VOID freeVSprite(struct VSprite *vsprite)
  537. LONG    line_size;
  538. LONG    plane_size;
  539. line_size = (LONG)sizeof(WORD) * vsprite->Width;
  540. plane_size = line_size * vsprite->Height;
  541. FreeMem(vsprite->BorderLine, line_size);
  542. FreeMem(vsprite->CollMask, plane_size);
  543. FreeMem(vsprite, (LONG)sizeof(*vsprite));
  544. /*-------------------------------------------------------------
  545. ** free the data created by makeBob()
  546. ** it's important that rasdepth match the depth you
  547. ** passed to makeBob() when this gel was made.
  548. ** assumes images deallocated elsewhere.
  549. VOID freeBob(struct Bob *bob, LONG rasdepth)
  550. LONG    rassize;
  551. rassize =  (LONG)sizeof(UWORD) *
  552. \s    bob->BobVSprite->Width * bob->BobVSprite->Height * rasdepth;
  553. if (bob->DBuffer != NULL)
  554. \sFreeMem(bob->DBuffer->BufBuffer, rassize);
  555. \sFreeMem(bob->DBuffer, (LONG)sizeof(struct DBufPacket));
  556. FreeMem(bob->SaveBuffer, rassize);
  557. freeVSprite(bob->BobVSprite);
  558. FreeMem(bob, (LONG)sizeof(*bob));
  559. /*-------------------------------------------------------------
  560. ** free the data created by makeComp()
  561. ** it's important that rasdepth match the depth you
  562. ** passed to makeComp() when this gel was made.
  563. ** assumes images deallocated elsewhere.
  564. VOID freeComp(struct AnimComp *myComp, LONG rasdepth)
  565. freeBob(myComp->AnimBob, rasdepth);
  566. FreeMem(myComp, (LONG)sizeof(struct AnimComp));
  567. /*-------------------------------------------------------------
  568. ** free the data created by makeSeq()
  569. ** Complimentary to makeSeq(), this routine goes through the NextSeq
  570. ** pointers and frees the Components
  571. ** This routine only goes forward through the list, and so
  572. ** it must be passed the first component in the sequence, or the sequence
  573. ** must be circular (which is guaranteed if you use makeSeq()).
  574. ** it's important that rasdepth match the depth you
  575. ** passed to makeSeq() when this gel was made.
  576. ** assumes images deallocated elsewhere.
  577. VOID freeSeq(struct AnimComp *headComp, LONG rasdepth)
  578. struct AnimComp *curComp;
  579. struct AnimComp *nextComp;
  580. /* this is freeing a loop of AnimComps, hooked together by the
  581. ** NextSeq and PrevSeq pointers.
  582. /* break the NextSeq loop, so we get a NULL at the end of the list. */
  583. headComp->PrevSeq->NextSeq = NULL;
  584. curComp = headComp;         /* get the start of the list */
  585. while (curComp != NULL)
  586. \snextComp = curComp->NextSeq;
  587. \sfreeComp(curComp, rasdepth);
  588. \scurComp = nextComp;
  589. /*-------------------------------------------------------------
  590. ** free an animation object (list of sequences).
  591. ** freeOb() goes through the NextComp pointers, starting at the AnimObs'
  592. ** HeadComp, and frees every sequence.
  593. ** it only goes forward. It then frees the Object itself.
  594. ** assumes images deallocated elsewhere.
  595. VOID freeOb(struct AnimOb *headOb, LONG rasdepth)
  596. struct AnimComp *curSeq;
  597. struct AnimComp *nextSeq;
  598. curSeq = headOb->HeadComp;          /* get the start of the list */
  599. while (curSeq != NULL)
  600. \snextSeq = curSeq->NextComp;
  601. \sfreeSeq(curSeq, rasdepth);
  602. \scurSeq = nextSeq;
  603. FreeMem(headOb, (LONG)sizeof(struct AnimOb));
  604. \B\lr<122>4) /* Collide.c */\b
  605. /* This is an example that shows how to do collision detection between
  606. ** multiple animation objects and between animation objects and the border.
  607. ** Lattice C 5.04
  608. ** lc -b1 -cfist -v -y -ocollide.o collide.c
  609. ** lc -b1 -cfist -v -y -oanimtools.o animtools.c
  610. ** blink from lib:c.o collide.o animtools.o
  611. **       library lib:lc.lib lib:amiga.lib to collide
  612. #include <exec/types.h>
  613. #include <intuition/intuition.h>
  614. #include <graphics/gels.h>
  615. #include <graphics/collide.h>
  616. #include <exec/memory.h>
  617. #include <libraries/dos.h>
  618. #include "animtools.h"
  619. #include "animtools_proto.h"
  620. #include <stdlib.h>
  621. #include <stdio.h>
  622. #include <proto/all.h>
  623. int CXBRK(void) { return(0); }
  624. /* prototypes for functions in this file */
  625. VOID __stdargs __saveds hit_routine(struct VSprite *vs1,struct VSprite *vs2);
  626. VOID __stdargs __saveds bounceWall(struct VSprite *vs1,LONG borderflags);
  627. struct AnimOb *setupBoing(SHORT dbufing);
  628. VOID runAnimation(struct Window *win, SHORT dbufing,
  629. \s              struct AnimOb **animKey, struct BitMap **myBitMaps);
  630. LONG setupPlanes(struct BitMap *bitMap, LONG depth, LONG width, LONG height);
  631. struct BitMap **setupBitMaps(LONG depth, LONG width, LONG height);
  632. VOID freePlanes(struct BitMap *bitMap, LONG depth, LONG width, LONG height);
  633. VOID freeBitMaps(struct BitMap **myBitMaps,
  634. \s                LONG depth, LONG width, LONG height);
  635. struct GelsInfo *setupDisplay(struct Window **win, SHORT dbufing,
  636. \s                          struct BitMap **myBitMaps);
  637. VOID drawGels(struct Window *win, struct AnimOb **animKey,
  638. \s          SHORT dbufing, WORD *toggleFrame, struct BitMap **myBitMaps);
  639. #define RBMWIDTH  320
  640. #define RBMHEIGHT 200
  641. #define RBMDEPTH    4
  642. struct NewScreen ns =
  643. \s0, 0, 320, 200, 2, 0, 1, NULL,
  644. \sCUSTOMSCREEN, NULL, "Collision With AnimObs", NULL, NULL
  645. struct NewWindow nw =
  646. \s50, 50, 220, 100, -1, -1, CLOSEWINDOW,
  647. \sWINDOWCLOSE | RMBTRAP, NULL, NULL, "Close Window to Stop", NULL,
  648. \sNULL, 150, 100, 150, 100, CUSTOMSCREEN
  649. struct IntuitionBase *IntuitionBase = NULL;
  650. struct GfxBase       *GfxBase       = NULL;
  651. int return_code;
  652. /* these give the number of frames (COUNT), size (HEIGHT, WIDTH, DEPTH),
  653. ** and word width (WWIDTH) of the animated object.
  654. */\lr<124>
  655. \lr<120>#define BOING_COUNT     6
  656. #define BOING_HEIGHT    25
  657. #define BOING_WIDTH     32
  658. #define BOING_DEPTH      1
  659. #define BOING_WWIDTH    ((BOING_WIDTH + 15) / 16)
  660. /* these are the IDs for the system to use for the three objects.
  661. ** these numbers will be used for the collision detection system.
  662. ** Do not use zero (0), as it is reserved by the collision system
  663. ** for border hits (see graphics/collide.h, BORDERHIT.)
  664. #define BOING_1     2
  665. #define BOING_2     3
  666. #define BOING_3     4
  667. /* these are the number of counts that each frame is displayed.
  668. ** they are all one, so each frame is displayed once then the
  669. ** animation system will move on to the next in the sequence
  670. SHORT boing3Times[BOING_COUNT] = { 1, 1, 1, 1, 1, 1 };
  671. /* these are all set to zero as we do not want anything added
  672. ** to the X and Y positions using ring motion control.
  673. ** all movement is done using the acceleration and velocity
  674. ** values.
  675. SHORT boing3YTranses[BOING_COUNT] = { 0, 0, 0, 0, 0, 0 };
  676. SHORT boing3XTranses[BOING_COUNT] = { 0, 0, 0, 0, 0, 0 };
  677. /* no special routines to call when each anim comp is displayed */
  678. WORD (*boing3CRoutines[BOING_COUNT])(struct AnimComp *) =
  679. \s{ NULL, NULL, NULL, NULL, NULL, NULL };
  680. UWORD __chip boing3Image[BOING_COUNT][BOING_WWIDTH * BOING_HEIGHT * BOING_DEPTH] =
  681. \s/*----- bitmap Boing, frame 0:  w = 32, h = 25 ------ */
  682. \s    {
  683. \s    0x0023, 0x0000,  0x004E, 0x3000,  0x00E3, 0x3A00,  0x03C3, 0xC900,
  684. \s    0x0787, 0x8780,  0x108F, 0x8700,  0x31F7, 0x8790,  0x61F0, 0x4790,
  685. \s    0x63E0, 0xFB90,  0x43E0, 0xF848,  0x3BC0, 0xF870,  0x3801, 0xF870,
  686. \s    0x383D, 0xF070,  0x387E, 0x1070,  0x387C, 0x0EE0,  0xD87C, 0x1F10,
  687. \s    0x467C, 0x1E10,  0x479C, 0x1E30,  0x6787, 0x3E20,  0x0787, 0xCC60,
  688. \s    0x0F0F, 0x8700,  0x048F, 0x0E00,  0x0277, 0x1C00,  0x0161, 0xD800,
  689. \s    0x0027, 0x2000,
  690. \s    },
  691. \s/*----- bitmap Boing, frame 1:  w = 32, h = 25 ------ */
  692. \s    {
  693. \s    0x0031, 0x8000,  0x0107, 0x1800,  0x00F0, 0x1900,  0x09E1, 0xEC80,
  694. \s    0x13C1, 0xE340,  0x1803, 0xE380,  0x387B, 0xC390,  0x30F8, 0x01D0,
  695. \s    0x70F8, 0x3DC0,  0xE1F0, 0x3E08,  0x9DF0, 0x7C30,  0x9E30, 0x7C30,
  696. \s    0x9E1C, 0x7C30,  0x1C1F, 0x9C30,  0x1C1F, 0x0630,  0x7C1F, 0x0780,
  697. \s    0x623F, 0x0798,  0x63DE, 0x0F10,  0x23C1, 0x0F20,  0x33C3, 0xEE20,
  698. \s    0x0BC3, 0xC380,  0x0647, 0xC700,  0x023F, 0x8E00,  0x0130, 0xF800,
  699. \s    0x0033, 0x8000,
  700. \s    },
  701. \s/*----- bitmap Boing, frame 2:  w = 32, h = 25 ------ */
  702. \s    {
  703. \s    0x0019, 0xC000,  0x0103, 0x8800,  0x0278, 0x8D00,  0x0CF0, 0xFE80,
  704. \s    0x11F0, 0xF140,  0x0E60, 0xF1E0,  0x1C39, 0xF0C0,  0x1C3E, 0x30C0,
  705. \s    0x387E, 0x0CE0,  0xF87C, 0x1F28,  0x8C7C, 0x1F18,  0x8F3C, 0x1F18,
  706. \s    0x8F06, 0x1E18,  0x8F07, 0xDE18,  0x8F07, 0xC018,  0x6E0F, 0xC1C0,
  707. \s    0x300F, 0x83C8,  0x31EF, 0x8390,  0x31F0, 0x8780,  0x11E0, 0xF720,
  708. \s    0x11E1, 0xF1C0,  0x0B61, 0xE300,  0x071B, 0xC600,  0x0138, 0x6C00,
  709. \s    0x0031, 0x8000,
  710. \s    },\lr<124>
  711. \s/*----- bitmap Boing, frame 3:  w = 32, h = 25 ------ */
  712. \s    {
  713. \s    0x001C, 0xE000,  0x01B1, 0xCC00,  0x031C, 0xC500,  0x0C3C, 0x3680,
  714. \s    0x1878, 0x7840,  0x2F70, 0x78E0,  0x0E08, 0x7860,  0x1E0F, 0xB860,
  715. \s    0x1C1F, 0x0460,  0xBC1F, 0x07B0,  0xC43F, 0x0788,  0xC7FE, 0x0788,
  716. \s    0xC7C0, 0x0F88,  0xC781, 0xEF88,  0xC783, 0xF118,  0x2783, 0xE0E8,
  717. \s    0x3983, 0xE1E0,  0x3863, 0xE1C0,  0x1878, 0xC1C0,  0x3878, 0x3380,
  718. \s    0x10F0, 0x78C0,  0x0B70, 0xF180,  0x0588, 0xE200,  0x009E, 0x2400,
  719. \s    0x0018, 0xC000,
  720. \s    },
  721. \s/*----- bitmap Boing, frame 4:  w = 32, h = 25 ------ */
  722. \s    {
  723. \s    0x000E, 0x6000,  0x00F8, 0xE400,  0x030F, 0xE600,  0x061E, 0x1300,
  724. \s    0x0C3E, 0x1C80,  0x27FC, 0x1C60,  0x0784, 0x3C60,  0x4F07, 0xFE20,
  725. \s    0x8F07, 0xC230,  0x1E0F, 0xC1F0,  0x620F, 0x83C8,  0x61CF, 0x83C8,
  726. \s    0x61E1, 0x83C8,  0x63E0, 0x63C8,  0x63E0, 0xF9C8,  0x03E0, 0xF878,
  727. \s    0x1DC0, 0xF860,  0x1C21, 0xF0E0,  0x5C3E, 0xF0C0,  0x0C3C, 0x11C0,
  728. \s    0x143C, 0x3C40,  0x09B8, 0x3880,  0x05C0, 0x7000,  0x00CF, 0x0400,
  729. \s    0x000C, 0x6000,
  730. \s    },
  731. \s/*----- bitmap Boing, frame 5:  w = 32, h = 25 ------ */
  732. \s    {
  733. \s    0x0026, 0x2000,  0x00FC, 0x7400,  0x0187, 0x7200,  0x030F, 0x0100,
  734. \s    0x0E0F, 0x0E80,  0x319F, 0x0E00,  0x23C6, 0x0F30,  0x63C1, 0xCF30,
  735. \s    0x4781, 0xF310,  0x0783, 0xE0D0,  0x7383, 0xE0E0,  0x70C3, 0xE0E0,
  736. \s    0x70F9, 0xE1E0,  0x70F8, 0x21E0,  0x70F8, 0x3FE0,  0x91F0, 0x3E38,
  737. \s    0x4FF0, 0x7C30,  0x4E10, 0x7C60,  0x4E0F, 0x7860,  0x2E1F, 0x08C0,
  738. \s    0x0E1E, 0x0E00,  0x049E, 0x1C80,  0x00E4, 0x3800,  0x00C7, 0x9000,
  739. \s    0x000E, 0x6000,
  740. \s    }
  741. /* these structures contain the initialization data for the animation
  742. ** sequence.
  743. NEWBOB newBoingBob =
  744. \sNULL, BOING_WWIDTH, BOING_HEIGHT, BOING_DEPTH, 0x2, 0x0,
  745. \sSAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0,0,0,
  746. NEWANIMSEQ newBoingSeq =
  747. \sNULL, (WORD *)boing3Image, boing3XTranses, boing3YTranses,
  748. \sboing3Times, boing3CRoutines, 0, BOING_COUNT, 0,
  749. /*-------------------------------------------------------------------------
  750. ** setupBoing()
  751. ** make a new animation object.  since all of the boing balls use the same
  752. ** underlying data, the initalization structures are hard-coded into the
  753. ** routine (newBoingBob and newBoingSeq.)
  754. ** return a pointer to the object if successful, NULL if failure.
  755. ** set a global error code on failure.
  756. struct AnimOb *setupBoing(SHORT dbufing)
  757. struct AnimOb   *bngOb;
  758. struct AnimComp *bngComp;
  759. if (NULL != (bngOb = AllocMem((LONG)sizeof(struct AnimOb), MEMF_CLEAR)))
  760. \snewBoingBob.nb_DBuf    = dbufing;     /* double-buffer status  */
  761. \snewBoingSeq.nas_HeadOb = bngOb;       /* pass down head object */
  762. \sif (NULL != (bngComp = makeSeq(&newBoingBob, &newBoingSeq)))
  763. \s    {
  764. \s    bngOb->HeadComp = bngComp;  /* the head comp is the one that */
  765. \s                                /* is returned by makeSeq()      */
  766. \s    return(bngOb);
  767. \s    }
  768. \sFreeMem(bngOb, (LONG)sizeof(struct AnimOb));
  769. return_code = RETURN_WARN;
  770. return(NULL);
  771. /*-------------------------------------------------------------------------
  772. ** runAnimation()
  773. ** a simple message handling loop that also draws the successive frames.
  774. VOID runAnimation(struct Window *win, SHORT dbufing,
  775. \s              struct AnimOb **animKey, struct BitMap **myBitMaps)
  776. struct IntuiMessage  *intuiMsg;
  777. WORD toggleFrame;
  778. /* toggleFrame is used to keep track of which frame of the double buffered
  779. ** screen we are currently displaying.  the variable must exist for the life
  780. ** of the displayed objects, so it is defined here.
  781. toggleFrame = 0;
  782. /* end the loop on a CLOSEWINDOW event */
  783. for (;;)
  784. \s/* draw the gels, then check for messages.
  785. \s** check the messages after each display so we get a quick response.
  786. \sdrawGels(win, animKey, dbufing, &toggleFrame, myBitMaps);
  787. \s/* quit on a control_c */
  788. \sif (SetSignal(0L,0L) & SIGBREAKF_CTRL_C)
  789. \s    return;
  790. \s/* check for a closewindow event, die if found */
  791. \swhile (intuiMsg = (struct IntuiMessage *)GetMsg(win->UserPort))
  792. \s    {
  793. \s    if (intuiMsg->Class == CLOSEWINDOW)
  794. \s        {
  795. \s        ReplyMsg((struct Message *)intuiMsg);
  796. \s        return;
  797. \s        }
  798. \s    ReplyMsg((struct Message *)intuiMsg);
  799. \s    }
  800. /*-------------------------------------------------------------------------
  801. ** setupPlanes()
  802. ** called only for double-buffered displays.
  803. ** allocate and clear each bit-plane in a bitmap structure.
  804. ** clean-up on failure.
  805. LONG setupPlanes(struct BitMap *bitMap, LONG depth, LONG width, LONG height)
  806. SHORT plane_num ;
  807. for (plane_num = 0; plane_num < depth; plane_num++)
  808. \sif (NULL != (bitMap->Planes[plane_num] =
  809. \s                (PLANEPTR)AllocRaster(width, height)))
  810. \s    BltClear((APTR)(bitMap->Planes[plane_num]), (width / 8) * height, 1);
  811. \selse
  812. \s    {
  813. \s    freePlanes(bitMap, depth, width, height);
  814. \s    return_code = RETURN_WARN;
  815. \s    return(NULL);
  816. \s    }
  817. return(TRUE);
  818. /*-------------------------------------------------------------------------
  819. ** setupBitMaps()
  820. ** allocate the two bitmaps for a double-buffered display.
  821. ** routine only called when the display is double-buffered.
  822. struct BitMap **setupBitMaps(LONG depth, LONG width, LONG height)
  823. static struct BitMap *myBitMaps[2];
  824. /* allocate the two bit-map structures. these do not have to be in CHIP */
  825. if (NULL != (myBitMaps[0] =
  826. \s    (struct BitMap *)AllocMem((LONG)sizeof(struct BitMap), MEMF_CLEAR)))
  827. \sif (NULL != (myBitMaps[1] =
  828. \s    (struct BitMap *)AllocMem((LONG)sizeof(struct BitMap), MEMF_CLEAR)))
  829. \s    {
  830. \s    /* initialize the bit maps to the correct size. */
  831. \s    InitBitMap(myBitMaps[0], (BYTE)depth, (SHORT)width, (SHORT)height);
  832. \s    InitBitMap(myBitMaps[1], (BYTE)depth, (SHORT)width, (SHORT)height);
  833. \s    /* allocate and initialize the bit-planes for the bit-maps. */
  834. \s    if (NULL != setupPlanes(myBitMaps[0], depth, width, height))
  835. \s        {
  836. \s        if (NULL != setupPlanes(myBitMaps[1], depth, width, height))
  837. \s            return(myBitMaps);
  838. \s        freePlanes(myBitMaps[0], depth, width, height);
  839. \s        }
  840. \s    FreeMem(myBitMaps[1], (LONG)sizeof(struct BitMap));
  841. \s    }
  842. \sFreeMem(myBitMaps[0], (LONG)sizeof(struct BitMap));
  843. /* on failure, everything is freed and a global return code is set. */
  844. return_code = RETURN_WARN;
  845. return(NULL);
  846. /*-------------------------------------------------------------------------
  847. ** freePlanes()
  848. ** free all of the bit-planes in a bit-map structure.
  849. VOID freePlanes(struct BitMap *bitMap, LONG depth, LONG width, LONG height)
  850. SHORT plane_num ;
  851. for (plane_num = 0; plane_num < depth; plane_num++)
  852. \sif (NULL != bitMap->Planes[plane_num])
  853. \s    FreeRaster(bitMap->Planes[plane_num], (USHORT)width, (USHORT)height);
  854. /*-------------------------------------------------------------------------
  855. ** freeBitMaps()
  856. ** free the two bit-maps from the double buffered display.
  857. ** the bit-planes are freed first, then the bit-map structures.
  858. VOID freeBitMaps(struct BitMap **myBitMaps, LONG depth, LONG width, LONG height)
  859. freePlanes(myBitMaps[0], depth, width, height);
  860. freePlanes(myBitMaps[1], depth, width, height);
  861. FreeMem(myBitMaps[0], (LONG)sizeof(struct BitMap));
  862. FreeMem(myBitMaps[1], (LONG)sizeof(struct BitMap));
  863. /*-------------------------------------------------------------------------
  864. ** setupDisplay()
  865. ** open the screen and the window for the display.
  866. ** if using double buffered display, assume the bit-maps have been opened
  867. ** and correctly set-up.
  868. struct GelsInfo *setupDisplay(struct Window **win, SHORT dbufing,
  869. \s                          struct BitMap **myBitMaps)
  870. struct GelsInfo    *gInfo;
  871. struct Screen      *screen;
  872. /* if double-buffered, set-up the new screen structure for custom bit map */
  873. if (dbufing)
  874. \sns.Type |= CUSTOMBITMAP;
  875. \sns.CustomBitMap = myBitMaps[0];
  876. /* open everything.  check for failure. */
  877. if ((screen = (struct Screen *)OpenScreen(&ns)) != NULL)
  878. \snw.Screen = screen;
  879. \sif ((*win = (struct Window *)OpenWindow(&nw)) != NULL)
  880. \s    {
  881. \s    if (dbufing)
  882. \s        {
  883. \s        /* we are double buffered.  set the rastport for it. */
  884. \s        (*win)->WScreen->RastPort.Flags = DBUFFER;
  885. \s        /* this copies the intuition display (close gadget) to the
  886. \s        ** second bit-map so the display does not flash when we change
  887. \s        ** between them.
  888. \s        */
  889. \s        (*win)->WScreen->RastPort.BitMap = myBitMaps[1];
  890. \s        BltBitMapRastPort(myBitMaps[0], 0,0, &(*win)->WScreen->RastPort,
  891. \s                    0,0, RBMWIDTH, RBMHEIGHT, 0xC0);
  892. \s        (*win)->WScreen->RastPort.BitMap = myBitMaps[0];
  893. \s        }
  894. \s    /* ready the gel system for accepting objects
  895. \s    ** this is only done once for each rastport in use.
  896. \s    */
  897. \s    if (NULL != (gInfo = setupGelSys(&(*win)->WScreen->RastPort, 0xFC)))
  898. \s        return(gInfo);
  899. \s    CloseWindow(*win);
  900. \s    }
  901. \sCloseScreen(screen);
  902. /* on an error everything is cleaned-up, and a global return code is set. */
  903. return_code = RETURN_WARN;
  904. return(NULL);
  905. /*-------------------------------------------------------------------------
  906. ** drawGels()
  907. ** handle the update of the display.  Animate the simulation and check for
  908. ** collisions.  If the screen is double buffered, swap the bit map as
  909. ** required.
  910. VOID drawGels(struct Window *win, struct AnimOb **animKey, SHORT dbufing,
  911. \s          WORD *toggleFrame, struct BitMap **myBitMaps)
  912. /* do the required animation stuff.  you must sort both after the animate
  913. ** call and after the collision call.
  914. Animate((struct AnimOb *)animKey, &win->WScreen->RastPort);
  915. SortGList(&win->WScreen->RastPort);
  916. DoCollision(&win->WScreen->RastPort);
  917. SortGList(&win->WScreen->RastPort);
  918. /* toggle if double buffered */
  919. if (dbufing)
  920. \swin->WScreen->ViewPort.RasInfo->BitMap = myBitMaps[*toggleFrame];
  921. /* draw the new position of the gels into the screen. */
  922. DrawGList(&win->WScreen->RastPort, &win->WScreen->ViewPort);
  923. /* if using a double buffered display, you have a more complicated
  924. ** update procedure.
  925. ** if not, then simply use WaitTOF().
  926. if (dbufing)
  927. \sMakeScreen(win->WScreen);
  928. \sRethinkDisplay();
  929. \s*toggleFrame ^= 1;
  930. \swin->WScreen->RastPort.BitMap = myBitMaps[*toggleFrame];
  931. \sWaitTOF();
  932. /*-------------------------------------------------------------------------
  933. ** bounceWall()
  934. ** handle bouncing the animation objects off of the walls.
  935. ** use __stdargs and __saveds because this routine is not directly called
  936. ** by this program.  The call to DoCollision() causes a call back to
  937. ** this routine when an animation object comes in contact with a wall.
  938. ** __stdargs says the arguments are passed on the stack.
  939. ** __saveds says to restore the data segment pointer on entry to the routine.
  940. VOID __stdargs __saveds bounceWall(struct VSprite *vs1,LONG borderflags)
  941. struct AnimOb *ob;
  942. /* get a pointer to the object from the sprite pointer. */
  943. ob = vs1->VSBob->BobComp->HeadOb;
  944. /* check for hits and act apropriately.
  945. ** for right and left, reverse the x velocity if the object is moving
  946. ** towards the wall (it may have already reversed but still be in contact
  947. ** with the wall.)
  948. ** for the bottom and top you also have to subtract out the acceleration.
  949. if (((borderflags & RIGHTHIT) && (ob->XVel > 0)) ||
  950. \s((borderflags & LEFTHIT) && (ob->XVel < 0)))
  951. \sob->XVel = -(ob->XVel);
  952. else if (((borderflags & TOPHIT) && (ob->YVel < 0)) ||
  953. \s     ((borderflags & BOTTOMHIT) && (ob->YVel > 0)))
  954. \sob->YVel -= ob->YAccel;
  955. \sob->YVel = -(ob->YVel);
  956. /*-------------------------------------------------------------------------
  957. ** hit_routine()
  958. ** handle the collision between two animation objects.
  959. ** this routine simulates objects bouncing off of each other.
  960. ** this does not do a very good job of it, it does not take into account
  961. ** the angle of the collision or real physics.
  962. ** if anyone wants to fix it, please feel free.
  963. ** use __stdargs and __saveds because this routine is not directly called
  964. ** by this program.  The call to DoCollision() causes a call back to
  965. ** this routine when two animation objects overlap.
  966. ** __stdargs says the arguments are passed on the stack.
  967. ** __saveds says to restore the data segment pointer on entry to the routine.
  968. VOID __stdargs __saveds hit_routine(struct VSprite *vs1,struct VSprite *vs2)
  969. LONG vel1, vel2;
  970. /* check that the bob is not being removed!  This is due to a 1.3 bug
  971. ** where all bobs are tested for collision, even the ones that are in
  972. ** the process of being removed.  See text for more information.
  973. ** bobs are moved to a very large negative position as they are being
  974. ** removed.  if the BOBSAWAY flag is set, then both bobs in the collision
  975. ** are in the process of being removed--don't do anything in the collision
  976. ** routine.
  977. if (!(vs1->VSBob->Flags & BOBSAWAY))
  978. \s/* cache the velocity values
  979. \s** Do the X values first (order is not important.)
  980. \svel1 = vs1->VSBob->BobComp->HeadOb->XVel;
  981. \svel2 = vs2->VSBob->BobComp->HeadOb->XVel;
  982. \s/* if the two objects are moving in the opposite direction (X component)
  983. \s** then negate the velocities.
  984. \s** else swap the velocities.
  985. \sif (((vel1 > 0) && (vel2 < 0)) || ((vel1 < 0) && (vel2 > 0)))
  986. \s    {
  987. \s    vs1->VSBob->BobComp->HeadOb->XVel = -vel1;
  988. \s    vs2->VSBob->BobComp->HeadOb->XVel = -vel2;
  989. \s    }
  990. \selse
  991. \s    {
  992. \s    vs1->VSBob->BobComp->HeadOb->XVel = vel2;
  993. \s    vs2->VSBob->BobComp->HeadOb->XVel = vel1;
  994. \s    }
  995. \s/* cache the velocity values
  996. \s** Do the Y values second (order is not important.)
  997. \svel1 = vs1->VSBob->BobComp->HeadOb->YVel;
  998. \svel2 = vs2->VSBob->BobComp->HeadOb->YVel;
  999. \s/* if the two objects are moving in the opposite direction (Y component)
  1000. \s** then negate the velocities.
  1001. \s** else swap the velocities.
  1002. \sif (((vel1 > 0) && (vel2 < 0)) || ((vel1 < 0) && (vel2 > 0)))
  1003. \s    {
  1004. \s    vs1->VSBob->BobComp->HeadOb->YVel = -vel1;
  1005. \s    vs2->VSBob->BobComp->HeadOb->YVel = -vel2;
  1006. \s    }
  1007. \selse
  1008. \s    {
  1009. \s    vs1->VSBob->BobComp->HeadOb->YVel = vel2;
  1010. \s    vs2->VSBob->BobComp->HeadOb->YVel = vel1;
  1011. \s    }
  1012. /*-------------------------------------------------------------------------
  1013. ** main routine
  1014. ** run a double buffered display if the user puts any arguments on the
  1015. ** command line.
  1016. ** open libraries, set-up the display, set-up the animation system and
  1017. ** the objects, set-up collisions between objects and against walls,
  1018. ** and run the thing.
  1019. ** clean-up and close resources when done.
  1020. VOID main(int argc, char **argv)
  1021. struct BitMap   **myBitMaps;
  1022. struct AnimOb    *boingOb;
  1023. struct AnimOb    *boing2Ob;
  1024. struct AnimOb    *boing3Ob;
  1025. struct Window    *win;
  1026. struct Screen    *screen;
  1027. struct GelsInfo  *gInfo;
  1028. struct AnimOb    *animKey;
  1029. SHORT dbufing;
  1030. return_code = RETURN_OK;
  1031. /* if any arguments, use double-buffering */
  1032. if (argc > 1)
  1033. \sdbufing = 1;
  1034. \sdbufing = 0;
  1035. /* open required libraries */
  1036. if (NULL == (IntuitionBase = (struct IntuitionBase *)
  1037. \s    OpenLibrary("intuition.library", 33L)))
  1038. \sreturn_code = RETURN_FAIL;
  1039. \sif (NULL == (GfxBase = (struct GfxBase *)
  1040. \s        OpenLibrary("graphics.library", 33L)))
  1041. \s    return_code = RETURN_FAIL;
  1042. \selse
  1043. \s    {
  1044. \s    /* note that setupBitMaps() will only be called if
  1045. \s    ** we are double buffering
  1046. \s    */
  1047. \s    if ((!dbufing) ||
  1048. \s        (NULL != (myBitMaps=setupBitMaps(RBMDEPTH,RBMWIDTH,RBMHEIGHT))))
  1049. \s        {
  1050. \s        if (NULL != (gInfo = setupDisplay(&win,dbufing,myBitMaps)))
  1051. \s            {
  1052. \s            /* you have to initialize the animation key
  1053. \s            ** before you use it.
  1054. \s            */
  1055. \s            InitAnimate(&animKey);
  1056. \s            /* set-up the first boing ball.
  1057. \s            ** all of these use the same data, hard coded into setupBoing().
  1058. \s            ** change the color by changing PlanePick.
  1059. \s            ** set the ID of the ball (MeMask) to BOING_1.
  1060. \s            ** HitMask = 0xFF means that it will collide with everything.
  1061. \s             */
  1062. \s            newBoingBob.nb_PlanePick = 0x2;
  1063. \s            newBoingBob.nb_MeMask    = 1L<<BOING_1;
  1064. \s            newBoingBob.nb_HitMask   = 0xFF;
  1065. \s            if (NULL != (boingOb = setupBoing(dbufing)))
  1066. \s                {
  1067. \s                /* pick an initial position, velocity and acceleration
  1068. \s                ** and add the object to the system.  NOTE that the
  1069. \s                ** Y-velocity and X-acceleration are not set (they default
  1070. \s                ** to zero.)  This means that the objects will maintain
  1071. \s                ** a constant movement to the left or right, and will
  1072. \s                ** rely on the Y accelleration for the downward movement.
  1073. \s                ** The collision routines change these values, producing
  1074. \s                ** bouncing off of walls and other objects.
  1075. \s                **
  1076. \s                ** NOTE:  ANFRACSIZE is a value that shifts animation
  1077. \s                ** constants past an internal decimal point.  If you
  1078. \s                ** do not do this, then the values will only be some
  1079. \s                ** fraction of what you expect.  See the Rom Kernel
  1080. \s                ** Manual:  Libraries and Devices.
  1081. \s                */
  1082. \s                boingOb->AnY    = 10 << ANFRACSIZE;
  1083. \s                boingOb->AnX    = 250 << ANFRACSIZE;
  1084. \s                boingOb->XVel   = -(4 << ANFRACSIZE);
  1085. \s                boingOb->YAccel = 70;
  1086. \s                AddAnimOb(boingOb, (APTR)&animKey,
  1087. \s                            &win->WScreen->RastPort);
  1088. \s                /* do the second object--see above comments. */
  1089. \s                newBoingBob.nb_PlanePick = 0x1;
  1090. \s                newBoingBob.nb_MeMask    = 1L<<BOING_2;
  1091. \s                newBoingBob.nb_HitMask   = 0xFF;
  1092. \s                if (NULL != (boing2Ob = setupBoing(dbufing)))
  1093. \s                    {
  1094. \s                    boing2Ob->AnY    = 50 << ANFRACSIZE;
  1095. \s                    boing2Ob->AnX    = 50 << ANFRACSIZE;
  1096. \s                    boing2Ob->XVel   = 3 << ANFRACSIZE;
  1097. \s                    boing2Ob->YAccel = 70;
  1098. \s                    AddAnimOb(boing2Ob, (APTR)&animKey,
  1099. \s                            &win->WScreen->RastPort);
  1100. \s                    /* do the third object--see above comments.
  1101. \s                    ** here we also use PlaneOnOff to change the color.
  1102. \s                    */
  1103. \s                    newBoingBob.nb_PlanePick = 0x1;
  1104. \s                    newBoingBob.nb_PlaneOnOff= 0x2;
  1105. \s                    newBoingBob.nb_MeMask    = 1L<<BOING_3;
  1106. \s                    newBoingBob.nb_HitMask   = 0xFF;
  1107. \s                    if (NULL != (boing3Ob = setupBoing(dbufing)))
  1108. \s                        {
  1109. \s                        boing3Ob->AnY    = 80 << ANFRACSIZE;
  1110. \s                        boing3Ob->AnX    = 150<< ANFRACSIZE;
  1111. \s                        boing3Ob->XVel   = 2 << ANFRACSIZE;
  1112. \s                        boing3Ob->YAccel = 70;
  1113. \s                        AddAnimOb(boing3Ob, (APTR)&animKey,
  1114. \s                                &win->WScreen->RastPort);
  1115. \s                        /* set up the collisions between boing balls.
  1116. \s                        ** NOTE that they all call the same routine.
  1117. \s                        */
  1118. \s                        SetCollision(BOING_1,hit_routine,gInfo);
  1119. \s                        SetCollision(BOING_2,hit_routine,gInfo);
  1120. \s                        SetCollision(BOING_3,hit_routine,gInfo);
  1121. \s                        /* set the collisions with the walls. */
  1122. \s                        SetCollision(BORDERHIT,bounceWall,gInfo);
  1123. \s                        /* everything set-up...run the animation. */
  1124. \s                        runAnimation(win, dbufing, &animKey, myBitMaps);
  1125. \s                        /* done...
  1126. \s                        ** free-up everything and clean up the mess.
  1127. \s                         */
  1128. \s                        freeOb(boing3Ob, RBMDEPTH);
  1129. \s                        }
  1130. \s                    freeOb(boing2Ob, RBMDEPTH);
  1131. \s                    }
  1132. \s                freeOb(boingOb, RBMDEPTH);
  1133. \s                }
  1134. \s            cleanupGelSys(gInfo, &win->WScreen->RastPort);
  1135. \s            screen = win->WScreen;
  1136. \s            CloseWindow(win);
  1137. \s            CloseScreen(screen);
  1138. \s            }
  1139. \s        if (dbufing)
  1140. \s            freeBitMaps(myBitMaps, RBMDEPTH, RBMWIDTH, RBMHEIGHT);
  1141. \s        }
  1142. \s    CloseLibrary((struct Library *)GfxBase);
  1143. \s    }
  1144. \sCloseLibrary((struct Library *)IntuitionBase);
  1145. /* return the global return code to the system. */
  1146. exit(return_code);
  1147. \B\I\O\ff<Bookman>\fs<14>A\.
  1148. hPBOX
  1149. O\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  1150.     PTXT
  1151. U\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 28\.
  1152.     PTXT
  1153. w\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  1154. .PBOX
  1155. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  1156. D/VPSGR
  1157. Black
  1158. Black
  1159. Black
  1160. Black
  1161. D>>PBOX
  1162. DAuPBOX
  1163. DG)PTXT
  1164. t\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  1165. p\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 29\I\O\ff<Bookman>\fs<14>\jl
  1166. R\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  1167. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  1168. VPBOX
  1169. 8PSGR
  1170. Black
  1171. Black
  1172. cPPAG
  1173. Black
  1174. Black
  1175. 8PBOX
  1176. xPTXT
  1177. O\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  1178. U\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 30\.
  1179. E'*PTXT
  1180. w\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  1181. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  1182. Et@PSGR
  1183. Black
  1184. Black
  1185. Ey    PPAG
  1186. Black
  1187. Black
  1188. E}mPBOX
  1189. t\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  1190. .PBOX
  1191. p\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 31\I\O\ff<Bookman>\fs<14>\jl
  1192. R\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  1193. <PBOX
  1194. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  1195. Black
  1196. Black
  1197. /PSGR
  1198. Black
  1199. Black
  1200. O\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  1201. F+.PBOX
  1202. F-}PTXT
  1203. U\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 32\.
  1204. w\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  1205. FwlPTXT
  1206. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  1207. zPSGR
  1208. Black
  1209. Black
  1210. YPSGR
  1211. Black
  1212. Black
  1213. wPBOX
  1214. t\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  1215. VPTXT
  1216. p\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 33\I\O\ff<Bookman>\fs<14>\jl
  1217. pPBOX
  1218. R\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  1219. *PTXT
  1220. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  1221. Black
  1222. Black
  1223. Black
  1224. Black
  1225. G6`PBOX
  1226. G8.PTXT
  1227. O\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  1228. GSYPTXT
  1229. U\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 34\.
  1230. Gr\PTXT
  1231. w\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  1232. lPBOX
  1233. RPTXT
  1234. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  1235. Black
  1236. Black
  1237. Black
  1238. Black
  1239. t\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  1240. 1PBOX
  1241. 1PTXT
  1242. p\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 35\I\O\ff<Bookman>\fs<14>\jl
  1243. TPBOX
  1244. R\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  1245. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  1246. HVDPSGR
  1247. Black
  1248. Black
  1249. H[)PSGR
  1250. Black
  1251. Black
  1252. H`NPBOX
  1253. HdePTXT
  1254. O\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  1255. CPBOX
  1256. U\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 36\.
  1257. w\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  1258. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  1259. Black
  1260. Black
  1261. iPSGR
  1262. Black
  1263. Black
  1264. lPBOX
  1265. t\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  1266. p\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 37\I\O\ff<Bookman>\fs<14>\jl
  1267. IM&PTXT
  1268. R\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  1269. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  1270. Black
  1271. Black
  1272. $PPAG
  1273. Black
  1274. Black
  1275. wPBOX
  1276. 5PTXT
  1277. O\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  1278. APTXT
  1279. U\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 38\.
  1280. w\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  1281. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  1282. rPBOX
  1283. Black
  1284. Black
  1285. J&:PBOX
  1286. J'gPSGR
  1287. Black
  1288. Black
  1289. J,%PBOX
  1290. J/zPBOX
  1291. J4$PTXT
  1292. t\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  1293. J_hPTXT
  1294. p\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 39\I\O\ff<Bookman>\fs<14>\jl
  1295. 4PBOX
  1296. R\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  1297. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  1298. YPBOX
  1299. Black
  1300. Black
  1301. $PBOX
  1302. yPSGR
  1303. Black
  1304. Black
  1305. bPTXT
  1306. O\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  1307. 0PTXT
  1308. U\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 40\.
  1309. "PBOX
  1310. w\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  1311. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  1312. KUkPBOX
  1313. KXZPSGR
  1314. Black
  1315. Black
  1316. K]'PPAG
  1317. Black
  1318. Black
  1319. KetPBOX
  1320. t\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  1321. !PBOX
  1322. ePTXT
  1323. p\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 41\I\O\ff<Bookman>\fs<14>\jl
  1324. _PBOX
  1325. R\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  1326. 8PBOX
  1327. IPTXT
  1328. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  1329. Black
  1330. Black
  1331. MPPAG
  1332. %PBOX
  1333. Black
  1334. Black
  1335. jPBOX
  1336. bPBOX
  1337. L    CPBOX
  1338. ?PTXT
  1339. O\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  1340. U\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 42\.
  1341. LJ3PTXT
  1342. w\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  1343. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  1344. XPSGR
  1345. Black
  1346. Black
  1347. gPPAG
  1348. Black
  1349. Black
  1350. zPBOX
  1351. yPBOX
  1352. t\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  1353. p\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 43\I\O\ff<Bookman>\fs<14>\jl
  1354. bPTXT
  1355. R\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  1356. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  1357. M;9PBOX
  1358. Black
  1359. Black
  1360. MB$PPAG
  1361. MC{PBOX
  1362. MEmPSGR
  1363. Black
  1364. Black
  1365. MJRPBOX
  1366. MR'PTXT
  1367. O\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  1368. U\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 44\.
  1369. ?PBOX
  1370. w\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  1371. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  1372. [PBOX
  1373. Black
  1374. Black
  1375. /PSGR
  1376. Black
  1377. Black
  1378. sPBOX
  1379. EPBOX
  1380. t\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  1381. p\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 45\I\O\ff<Bookman>\fs<14>\jl
  1382. R\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  1383. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  1384. Black
  1385. Black
  1386. EPSGR
  1387. Black
  1388. Black
  1389. GPBOX
  1390. }PBOX
  1391. XPTXT
  1392. O\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  1393. _PBOX
  1394. U\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 46\.
  1395. cPTXT
  1396. w\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  1397. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  1398. Black
  1399. Black
  1400. O%pPPAG
  1401. Black
  1402. Black
  1403. O-bPBOX
  1404. O0BPBOX
  1405. t\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  1406. ObYPTXT
  1407. p\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 47\I\O\ff<Bookman>\fs<14>\jl
  1408. R\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  1409. IPTXT
  1410. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  1411. =PSGR
  1412. Black
  1413. Black
  1414. dPPAG
  1415. TPBOX
  1416. vPSGR
  1417. Black
  1418. Black
  1419. YPTXT
  1420. O\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  1421. U\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 48\.
  1422. w\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  1423. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  1424. Black
  1425. Black
  1426. PuxPPAG
  1427. Black
  1428. Black
  1429. vPTXT
  1430. t\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  1431. }PTXT
  1432. p\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 49\I\O\ff<Bookman>\fs<14>\jl
  1433. R\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  1434. nPBOX
  1435. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  1436. Black
  1437. Black
  1438. Black
  1439. Black
  1440. Q(#PBOX
  1441. Q+%PBOX
  1442. O\n\B\ff<Helvetica>\fs<10>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Graphics\.
  1443. U\n\B\ff<Helvetica>\fs<10>\jc\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Page V - 50\.
  1444. Qh6PBOX
  1445. w\n\B\ff<Helvetica>\fs<10>\jr\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Collision Detection Between Animation Objects\.
  1446. uPBOX
  1447. `\n\B\I\O\ff<Helvetica>\fs<30>\lr<120>\ls<0.000>\ps<100>\t<0>\c<Black>Amiga Mail\ff<Times>
  1448. (PBOX
  1449. APSGR
  1450. Black
  1451. Black
  1452.